<template>
  <div class="digital-figure-container">
    <!-- 添加切换标签 -->
    <div class="tab-header">
      <el-tabs v-model="activeTab" class="feature-tabs" type="border-card">
        <el-tab-pane label="数字人形象生成" name="figure">
          <div class="content-wrapper">
            <div class="upload-section">
              <div class="section-title">
                <h2>生成数字人形象</h2>
                <p class="description">
                  基于已选择的人脸模型，生成个性化3D数字人形象
                </p>
              </div>

              <div class="face-preview-area">
                <div class="preview-title">已选人脸模型</div>
                <div class="face-preview">
                  <img
                    v-if="selectedFace.image"
                    :src="selectedFace.image"
                    alt="已选人脸"
                    class="face-preview-image"
                  />
                  <div v-else class="no-face-selected">
                    <el-icon :size="30"><Warning /></el-icon>
                    <p>您尚未选择人脸模型</p>
                    <el-button
                      type="primary"
                      size="small"
                      @click="goToFacePage"
                    >
                      前往生成人脸
                    </el-button>
                  </div>
                </div>
              </div>

              <!-- 添加人脸模型选择区域 -->
              <div class="face-gallery-section">
                <div class="section-header">
                  <h3>已保存的人脸模型</h3>
                  <el-button
                    v-if="savedFaces.length > 0"
                    type="primary"
                    link
                    size="small"
                    @click="viewMoreFaces"
                  >
                    查看更多
                  </el-button>
                </div>

                <div v-if="savedFaces.length > 0" class="face-gallery">
                  <div
                    v-for="face in savedFaces.slice(0, 4)"
                    :key="face.id"
                    class="face-card"
                    :class="{ active: selectedFace.id === face.id }"
                    @click="selectSavedFace(face)"
                  >
                    <img
                      :src="face.image"
                      :alt="face.alt"
                      class="gallery-face-image"
                    />
                    <div class="face-card-footer">
                      <span class="face-name">{{
                        face.style || face.alt
                      }}</span>
                      <span class="face-time">{{
                        formatCreationTime(face.createTime)
                      }}</span>
                    </div>
                  </div>
                </div>

                <div v-else class="empty-gallery">
                  <el-empty description="暂无保存的人脸模型" :image-size="60">
                    <template #description>
                      <p>您还没有保存任何人脸模型</p>
                    </template>
                    <el-button
                      type="primary"
                      size="small"
                      @click="goToFacePage"
                    >
                      前往生成人脸
                    </el-button>
                  </el-empty>
                </div>
              </div>

              <!-- 添加描述输入框 -->
              <div class="description-area">
                <div class="textarea-header">
                  <span class="required-mark">*</span>
                  <h3>形象描述</h3>
                </div>
                <el-input
                  v-model="figureDescription"
                  type="textarea"
                  :rows="4"
                  placeholder="请描述您想要生成的数字人形象特点，例如：服装风格、场景背景、肢体动作等"
                  resize="none"
                  maxlength="200"
                  show-word-limit
                />
              </div>

              <div class="style-selection">
                <div class="textarea-header">
                  <span class="required-mark">*</span>
                  <h3>风格选择</h3>
                </div>
                <el-radio-group v-model="selectedStyle" size="large">
                  <el-radio-button
                    v-for="style in styles"
                    :key="style.id"
                    :label="style.id"
                  >
                    {{ style.name }}
                  </el-radio-button>
                </el-radio-group>
              </div>

              <div class="generation-actions">
                <el-button
                  type="primary"
                  class="generate-btn"
                  :loading="isGenerating"
                  :disabled="!selectedFace.image"
                  @click="startGeneration"
                >
                  {{ isGenerating ? "生成中..." : "生成数字人形象" }}
                </el-button>
              </div>
            </div>

            <!-- 右侧生成结果展示区域 -->
            <div class="result-section">
              <div class="section-title">
                <div class="title-with-action">
                  <h2>生成结果</h2>
                  <el-button
                    v-if="hasResults"
                    type="primary"
                    class="regenerate-btn"
                    @click="regenerate"
                  >
                    <el-icon><Refresh /></el-icon> 换一个吧
                  </el-button>
                </div>
                <p class="description">
                  基于您的人脸模型和描述生成的数字人形象
                </p>
              </div>

              <div v-if="hasResults" class="result-grid">
                <div
                  v-for="(item, index) in resultItems"
                  :key="index"
                  class="result-item"
                >
                  <img :src="item.image" :alt="item.alt" class="result-image" />
                  <div class="result-item-footer">
                    <div class="result-style">{{ item.style }}</div>
                    <div class="result-actions">
                      <el-button
                        size="small"
                        type="primary"
                        plain
                        @click="downloadImage(item.image, item.alt)"
                      >
                        <el-icon><Download /></el-icon>
                        <span>下载</span>
                      </el-button>
                    </div>
                  </div>
                </div>
              </div>

              <div v-else class="empty-result">
                <el-empty description="暂无生成结果" />
                <p class="empty-tip">
                  请选择人脸模型并点击"生成数字人形象"按钮
                </p>
              </div>
            </div>
          </div>
        </el-tab-pane>
        <el-tab-pane label="汉服视频生成" name="video">
          <div class="content-wrapper">
            <div class="upload-section">
              <div class="section-title">
                <h2>生成汉服视频</h2>
                <p class="description">
                  基于上传的人物图片，生成个性化汉服视频
                </p>
              </div>

              <!-- 替换人脸预览区域为图片上传区域 -->
              <div class="upload-image-area">
                <div class="param-label">
                  <span class="required-mark">*</span>
                  <span>上传人物图片</span>
                </div>
                <div class="upload-container">
                  <el-upload
                    class="avatar-uploader"
                    action="#"
                    :auto-upload="false"
                    :show-file-list="false"
                    :on-change="handleVideoImageChange"
                  >
                    <div v-if="videoImageUrl" class="uploaded-image">
                      <img :src="videoImageUrl" class="avatar" />
                      <div class="image-hover-mask">
                        <el-icon class="upload-icon"><EditPen /></el-icon>
                        <span>更换图片</span>
                      </div>
                    </div>
                    <el-icon v-else class="avatar-uploader-icon"
                      ><Plus
                    /></el-icon>
                    <div v-if="!videoImageUrl" class="upload-text">
                      点击上传人物图片
                    </div>
                  </el-upload>
                  <div class="upload-tip">
                    推荐上传清晰的人物肖像照片，图片大小不超过5MB
                  </div>
                </div>
              </div>

              <!-- 视频生成参数设置 -->
              <div class="video-params">
                <div class="video-param-row">
                  <div class="param-group">
                    <div class="param-label">
                      <span class="required-mark">*</span>
                      <span>视频时长</span>
                    </div>
                    <el-select
                      v-model="videoDuration"
                      placeholder="请选择视频时长"
                      class="param-select"
                    >
                      <el-option label="15秒" value="15" />
                      <el-option label="30秒" value="30" />
                      <el-option label="60秒" value="60" />
                    </el-select>
                  </div>
                  <div class="param-group">
                    <div class="param-label">
                      <span class="required-mark">*</span>
                      <span>视频分辨率</span>
                    </div>
                    <el-select
                      v-model="videoResolution"
                      placeholder="请选择视频分辨率"
                      class="param-select"
                    >
                      <el-option label="720P" value="720" />
                      <el-option label="1080P" value="1080" />
                      <el-option label="4K" value="4k" />
                    </el-select>
                  </div>
                </div>

                <div class="param-group video-style-container">
                  <div class="param-label">
                    <span class="required-mark">*</span>
                    <span>视频风格</span>
                  </div>
                  <div class="button-group-container">
                    <el-radio-group
                      v-model="videoStyle"
                      size="large"
                      class="video-style-group"
                    >
                      <el-radio-button label="ancient">古风</el-radio-button>
                      <el-radio-button label="modern">现代</el-radio-button>
                      <el-radio-button label="martial">武侠</el-radio-button>
                    </el-radio-group>
                  </div>
                </div>

                <!-- 场景描述输入框 -->
                <div class="param-group">
                  <div class="param-label">
                    <span class="required-mark">*</span>
                    <span>场景描述</span>
                  </div>
                  <el-input
                    v-model="videoDescription"
                    type="textarea"
                    :rows="4"
                    placeholder="请描述您想要的视频场景，例如：场景背景、人物动作、环境氛围等"
                    resize="none"
                    maxlength="200"
                    show-word-limit
                    class="scene-textarea"
                  />
                </div>
              </div>

              <div class="generation-actions">
                <el-button
                  type="primary"
                  class="generate-video-btn"
                  :loading="isGenerating"
                  :disabled="!videoImageUrl"
                  @click="startVideoGeneration"
                >
                  {{ isGenerating ? "生成中..." : "生成汉服视频" }}
                </el-button>
              </div>
            </div>

            <!-- 优化右侧生成结果展示区域 -->
            <div class="result-section">
              <div class="section-title">
                <div class="title-with-action">
                  <h2>
                    {{
                      activeTab === "video" ? "视频生成结果" : "形象生成结果"
                    }}
                  </h2>
                  <el-button
                    v-if="hasResults"
                    type="primary"
                    class="regenerate-btn"
                    @click="regenerate"
                  >
                    <el-icon><Refresh /></el-icon> 换一个吧
                  </el-button>
                </div>
                <p class="description">
                  {{
                    activeTab === "video"
                      ? "基于您的人脸模型和描述生成的汉服视频"
                      : "基于您的人脸模型和描述生成的数字人形象"
                  }}
                </p>
              </div>

              <!-- 视频结果区域 -->
              <div
                v-if="hasResults && activeTab === 'video'"
                class="video-result-grid"
              >
                <div
                  v-for="(item, index) in videoResults"
                  :key="index"
                  class="video-result-item"
                >
                  <video
                    ref="videoPlayer"
                    controls
                    class="result-video"
                    :poster="item.poster"
                    @click="handleVideoClick"
                  >
                    <source :src="item.video" type="video/mp4" />
                    您的浏览器不支持视频播放
                  </video>
                  <div class="result-item-footer">
                    <div class="result-style">{{ item.style }}</div>
                    <div class="result-actions">
                      <el-button
                        size="small"
                        type="primary"
                        plain
                        @click="downloadVideo(item.video, item.style)"
                      >
                        <el-icon><Download /></el-icon>
                        <span>下载</span>
                      </el-button>
                    </div>
                  </div>
                </div>
              </div>

              <!-- 最近生成历史记录 -->
              <div
                v-if="activeTab === 'video' && recentVideoResults.length > 0"
                class="recent-history-section"
              >
                <div class="section-header">
                  <h3>最近生成记录 ({{ recentVideoResults.length }})</h3>
                </div>
                <div class="recent-videos-grid">
                  <div
                    v-for="(item, index) in recentVideoResults"
                    :key="index"
                    class="recent-video-item"
                    @click="playRecentVideo(item)"
                  >
                    <div class="recent-thumbnail">
                      <img
                        :src="item.poster || defaultPoster"
                        alt="视频缩略图"
                        class="thumbnail-image"
                      />
                      <div class="play-overlay">
                        <el-icon class="play-icon"
                          ><VideoCameraFilled
                        /></el-icon>
                      </div>
                    </div>
                    <div class="recent-item-info">
                      <div class="recent-style">{{ item.style }}</div>
                      <div class="recent-time">
                        {{ formatHistoryTime(item.createdAt) }}
                      </div>
                    </div>
                  </div>
                </div>
              </div>

              <!-- 形象结果区域 -->
              <div v-else-if="hasResults && activeTab !== 'video'" class="result-grid">
                <div
                  v-for="(item, index) in resultItems"
                  :key="index"
                  class="result-item"
                >
                  <img :src="item.image" :alt="item.alt" class="result-image" />
                  <div class="result-item-footer">
                    <div class="result-style">{{ item.style }}</div>
                    <div class="result-actions">
                      <el-button
                        size="small"
                        type="primary"
                        plain
                        @click="downloadImage(item.image, item.alt)"
                      >
                        <el-icon><Download /></el-icon>
                        <span>下载</span>
                      </el-button>
                    </div>
                  </div>
                </div>
              </div>

              <!-- 空结果提示 -->
              <div v-else-if="activeTab === 'video' && !hasResults && recentVideoResults.length === 0" class="empty-result">
                <el-empty description="暂无生成结果和历史记录" />
                <p class="empty-tip">
                  请上传人物图片并点击"生成汉服视频"按钮
                </p>
              </div>
              
              <div v-else-if="!hasResults && activeTab !== 'video'" class="empty-result">
                <el-empty description="暂无生成结果" />
                <p class="empty-tip">
                  请选择人脸模型并点击"生成数字人形象"按钮
                </p>
              </div>
            </div>
          </div>
        </el-tab-pane>
      </el-tabs>
    </div>

    <!-- 添加生成成功动画 -->
    <div v-if="showSuccessAnimation" class="success-animation-container">
      <div class="success-animation">
        <div class="dynamic-island">
          <div class="island-background">
            <div class="checkmark-wrapper">
              <svg
                class="checkmark"
                xmlns="http://www.w3.org/2000/svg"
                viewBox="0 0 52 52"
              >
                <circle
                  class="checkmark-circle"
                  cx="26"
                  cy="26"
                  r="25"
                  fill="none"
                />
                <path
                  class="checkmark-path"
                  fill="none"
                  d="M14.1 27.2l7.1 7.2 16.7-16.8"
                />
              </svg>
            </div>
            <p class="success-message">生成成功</p>
          </div>
        </div>
      </div>
    </div>

    <!-- 添加一个全局居中的进度显示区域 -->
    <div v-if="isGenerating" class="global-progress-container">
      <div class="global-progress-card">
        <div class="progress-header">
          <div class="progress-icon">
            <el-icon :size="36"><Loading /></el-icon>
          </div>
          <h3>正在生成数字人形象</h3>
        </div>

        <div class="progress-steps">
          <div
            v-for="(step, index) in progressSteps"
            :key="index"
            class="progress-step-item"
            :class="{ active: step.progress <= generationProgress }"
          >
            <div class="step-dot" />
            <div class="step-text">{{ step.text }}</div>
          </div>
        </div>

        <el-progress
          :percentage="generationProgress"
          :status="generationProgress === 100 ? 'success' : ''"
          :stroke-width="20"
          :color="progressBarColors"
        />

        <p class="progress-text">
          <span class="progress-percentage">{{ generationProgress }}%</span>
          {{ progressText }}
        </p>
      </div>
    </div>

    <!-- 添加人脸模型库对话框 -->
    <el-dialog v-model="facesDialogVisible" title="人脸模型库" width="680px">
      <div class="faces-library">
        <div v-if="savedFaces.length > 0" class="gallery-grid">
          <div
            v-for="face in savedFaces"
            :key="face.id"
            class="face-card-large"
            :class="{ active: selectedFace.id === face.id }"
            @click="selectSavedFace(face)"
          >
            <img :src="face.image" :alt="face.alt" class="gallery-face-image" />
            <div class="face-card-footer">
              <span class="face-name">{{ face.style || face.alt }}</span>
              <span class="face-time">{{
                formatCreationTime(face.createTime)
              }}</span>
            </div>
          </div>
        </div>

        <div v-else class="empty-gallery">
          <el-empty description="暂无保存的人脸模型" :image-size="80">
            <template #description>
              <p>您还没有保存任何人脸模型</p>
            </template>
            <el-button type="primary" size="small" @click="goToFacePage">
              前往生成人脸
            </el-button>
          </el-empty>
        </div>
      </div>
    </el-dialog>
  </div>
</template>

<script setup>
import {
  ref,
  reactive,
  computed,
  onMounted,
  onBeforeUnmount,
  nextTick,
  watch
} from "vue";
import {
  Download,
  Refresh,
  Loading,
  Warning,
  VideoCameraFilled,
  EditPen,
  Plus
} from "@element-plus/icons-vue";
import { ElMessage } from "element-plus";
import { useRouter } from "vue-router";
import {
  submitVideoTask,
  getVideoTaskResult,
  uploadImageForVideo,
  processVideoUrl,
  getVideo
} from "@/api/video"; // 导入新的视频API方法和处理URL的方法
import { useVideoStore } from "@/stores/video"; // 导入视频状态管理
import {
  createBlobUrlFromVideo,
  revokeBlobUrl,
  playVideo
} from "@/utils/videoHelper";

const router = useRouter();

// 常量配置
const CONSTANTS = {
  PROGRESS_INTERVAL: 200, // 进度条更新间隔(ms)
  ANIMATION_DELAY: 500 // 动画延迟时间(ms)
};

// 人脸和描述相关状态
const selectedFace = ref({
  image: "",
  alt: "",
  originalPhoto: ""
});
const figureDescription = ref("");
const hasResults = ref(false);

// 风格选择
const styles = [
  { id: "ancient", name: "古风" },
  { id: "modern", name: "现代" },
  { id: "business", name: "商务" },
  { id: "casual", name: "休闲" },
  { id: "fantasy", name: "奇幻" }
];
const selectedStyle = ref("ancient");

// 导入测试图片资源
import result1 from "./images/古风正面(1).png";
import result2 from "./images/古风正面 (2).png";
import result3 from "./images/古风正面 (3).png";
import result4 from "./images/古风正面 (4).png";

import resultJia1 from "./images/对比发饰1.jpeg";
import resultJia2 from "./images/对比发饰2.png";
import resultJia3 from "./images/对比发饰3.jpg";
import resultJia4 from "./images/对比发饰4.png";

// 测试结果数据集
const resultItems = ref([
  {
    image: result1,
    alt: "古风形象1",
    style: "古风写真"
  },
  {
    image: result2,
    alt: "古风形象2",
    style: "传统服饰"
  },
  {
    image: result3,
    alt: "古风形象3",
    style: "古典意境"
  },
  {
    image: result4,
    alt: "古风形象4",
    style: "人物特写"
  }
]);

// 生成进度相关状态
const isGenerating = ref(false);
const generationProgress = ref(0);
const progressSteps = reactive([
  { progress: 10, text: "加载人脸模型..." },
  { progress: 30, text: "分析描述特征..." },
  { progress: 50, text: "生成3D模型..." },
  { progress: 70, text: "应用风格转换..." },
  { progress: 90, text: "渲染最终效果..." },
  { progress: 100, text: "生成完成!" }
]);

// 计算当前进度文本
const progressText = computed(() => {
  const step = progressSteps.find(
    step => step.progress >= generationProgress.value
  );
  return step ? step.text : "准备生成...";
});

// 进度条颜色配置
const progressBarColors = [
  { color: "#64b5f6", percentage: 0 },
  { color: "#42a5f5", percentage: 50 },
  { color: "#2196f3", percentage: 100 }
];

// 动画控制状态
const showSuccessAnimation = ref(false);

// 添加到data部分
const savedFaces = ref([]);
const facesDialogVisible = ref(false);

// 添加新的状态变量
const activeTab = ref("figure");
const videoDuration = ref("15");
const videoResolution = ref("1080");
const videoStyle = ref("ancient");
const videoDescription = ref("");

// 添加视频结果数据
const videoResults = ref([]);

// 添加视频图片上传相关状态
const videoImageUrl = ref("");
const videoImageFile = ref(null);

// 添加Pinia存储
const videoStore = useVideoStore();

// 添加视频播放器引用
const videoPlayer = ref(null);
// 存储blob URL
const videoBlobUrls = ref([]);

// 添加最近生成视频历史记录
const recentVideoResults = ref([]);
const defaultPoster = ref(""); // 可以设置一个默认缩略图

/**
 * 格式化创建时间
 * @param {string} time - 时间字符串
 * @returns {string} 格式化后的时间
 */
const formatCreationTime = (time) => {
  if (!time) return "";
  return new Date(time).toLocaleString();
};

/**
 * 格式化历史记录时间
 * @param {string} time - 时间字符串
 * @returns {string} 格式化后的时间
 */
const formatHistoryTime = (time) => {
  if (!time) return "";
  return new Date(time).toLocaleString();
};

/**
 * 页面初始化时从localStorage获取选择的人脸数据和已保存的人脸模型列表
 */
onMounted(() => {
  // 获取当前选择的人脸
  const savedFace = localStorage.getItem("selectedFace");
  if (savedFace) {
    try {
      selectedFace.value = JSON.parse(savedFace);
    } catch (error) {
      console.error("解析已保存的人脸数据失败:", error);
      selectedFace.value = { image: "", alt: "", originalPhoto: "" };
    }
  }

  // 加载所有已保存的人脸模型
  loadSavedFaces();

  // 检查是否有正在进行中的视频任务
  checkPendingVideoTask();

  // 加载视频历史记录
  loadVideoHistory();
});

// 监听标签页切换，确保在切换到视频标签时加载历史记录
watch(activeTab, (newVal) => {
  if (newVal === "video") {
    // 重新加载视频历史记录
    loadVideoHistory();
    console.log("切换到视频标签，加载历史记录:", recentVideoResults.value);
  }
});

/**
 * 检查是否有正在进行中的视频任务
 */
const checkPendingVideoTask = async () => {
  const pendingTaskId = videoStore.pendingVideoTaskId;
  if (pendingTaskId) {
    try {
      ElMessage.info("正在检查上次未完成的视频生成任务...");
      const result = await getVideoTaskResult(pendingTaskId);
      console.log("检查上次任务结果:", result);
      console.log(1111);
      
      if (result.code === 200) {
        console.log(222);
        
        if (result.data !== null) {
          console.log(333);
          try {
            // 视频URL已返回，需要通过getVideo获取实际视频内容
            const videoResponse = await getVideo(result.data);
            console.log("videoResponse", videoResponse);
            
            // 检查videoResponse是否有效
            if (videoResponse && videoResponse.data) {
              console.log(videoResponse.data);
              // 视频已生成，显示结果（传入videoResponse.data）
              handleSuccessResult(videoResponse.data);
              console.log(99999);
            } else {
              throw new Error("视频数据无效");
            }
          } catch (videoError) {
            console.error("获取视频数据失败:", videoError);
            ElMessage.error("获取视频数据失败，请重试");
            // 清除任务ID，避免重复尝试获取失败的视频
            videoStore.clearPendingTask();
            return;
          }
          
          // 清除任务ID
          videoStore.clearPendingTask();
          console.log(10000);
          
          ElMessage.success("检测到上次生成的视频已完成，已自动加载结果");
          console.log(1000000000);
          
        } else {
          // 视频仍在生成中，提示用户
          ElMessage.info("您有一个视频正在生成中，请稍候查看结果");
        }
      }
    } catch (error) {
      console.log(777);
      console.error("检查上次任务失败:", error);
      // 清除可能无效的任务ID
      videoStore.clearPendingTask();
    }
  }
};

/**
 * 加载所有已保存的人脸模型
 */
const loadSavedFaces = () => {
  const savedFacesJson = localStorage.getItem("savedFaces") || "[]";
  try {
    const faces = JSON.parse(savedFacesJson);
    // 按时间降序排序，最新的在前面
    savedFaces.value = faces.sort((a, b) => {
      return new Date(b.createTime) - new Date(a.createTime);
    });
  } catch (error) {
    console.error("加载已保存的人脸模型失败:", error);
    savedFaces.value = [];
  }
};

/**
 * 选择已保存的人脸
 */
const selectSavedFace = async face => {
  selectedFace.value = face;
  localStorage.setItem("selectedFace", JSON.stringify(face));
  ElMessage.success("已选择人脸模型");

  const pendingTaskId = videoStore.pendingVideoTaskId;
  if (pendingTaskId) {
    try {
      ElMessage.info("正在检查上次未完成的视频生成任务...");
      const result = await getVideoTaskResult(pendingTaskId);
      console.log("检查上次任务结果:", result);
      console.log(444);
      
      if (result.code === 200) {
        // 修复条件判断，恢复if判断
        if (result.data !== null) {
          console.log(555);
          console.log("进来了");
          console.log("视频生成成功");
          
          try {
            // 视频URL已返回，需要通过getVideo获取实际视频内容
            const videoResponse = await getVideo(result.data);
            console.log("videoResponse", videoResponse);
            
            // 检查videoResponse是否有效
            if (videoResponse && videoResponse.data) {
              // 视频已生成，显示结果（传入videoResponse.data）
              handleSuccessResult(videoResponse.data);
            } else {
              throw new Error("视频数据无效");
            }
          } catch (videoError) {
            console.error("获取视频数据失败:", videoError);
            ElMessage.error("获取视频数据失败，请重试");
            // 清除任务ID，避免重复尝试获取失败的视频
            videoStore.clearPendingTask();
            return;
          }
          
          // 清除任务ID
          videoStore.clearPendingTask();
          ElMessage.success("检测到上次生成的视频已完成，已自动加载结果");
        } else {
          console.log(666);
          // 视频仍在生成中，提示用户
          ElMessage.info("您有一个视频正在生成中，请稍候查看结果");
        }
      }
    } catch (error) {
      console.log(777);
      console.error("检查上次任务失败:", error);
      // 清除可能无效的任务ID
      videoStore.clearPendingTask();
    }
  }
};

/**
 * 跳转到人脸生成页面
 */
const goToFacePage = () => {
  router.push("/3dDigitalMan/face");
};

/**
 * 开始生成流程
 */
const startGeneration = () => {
  if (isGenerating.value) return;

  if (!selectedFace.value.image) {
    ElMessage.warning("请先选择人脸模型");
    return;
  }

  if (!figureDescription.value) {
    ElMessage.warning("请填写形象描述");
    return;
  }

  startFigureGeneration();
};

/**
 * 开始数字人形象生成过程
 */
const startFigureGeneration = () => {
  isGenerating.value = true;
  generationProgress.value = 0;
  hasResults.value = false;
  showSuccessAnimation.value = false;

  const interval = setInterval(() => {
    if (generationProgress.value < 100) {
      generationProgress.value += 2;
    } else {
      clearInterval(interval);
      setTimeout(() => {
        isGenerating.value = false;
        showSuccessAnimation.value = true;

        setTimeout(() => {
          showSuccessAnimation.value = false;
          hasResults.value = true;

          // 根据选择的风格显示不同的结果集
          if (selectedStyle.value === "modern") {
            resultItems.value = [
              {
                image: resultJia1,
                alt: "现代形象1",
                style: "发饰风格1"
              },
              {
                image: resultJia2,
                alt: "现代形象2",
                style: "发饰风格2"
              },
              {
                image: resultJia3,
                alt: "现代形象3",
                style: "发饰风格3"
              },
              {
                image: resultJia4,
                alt: "现代形象4",
                style: "发饰风格4"
              }
            ];
          } else {
            resultItems.value = [
              {
                image: result1,
                alt: "古风形象1",
                style: "古风写真"
              },
              {
                image: result2,
                alt: "古风形象2",
                style: "传统服饰"
              },
              {
                image: result3,
                alt: "古风形象3",
                style: "古典意境"
              },
              {
                image: result4,
                alt: "古风形象4",
                style: "人物特写"
              }
            ];
          }
        }, 2000);
      }, CONSTANTS.ANIMATION_DELAY);
    }
  }, CONSTANTS.PROGRESS_INTERVAL);
};

/**
 * 重新生成
 */
const regenerate = () => {
  if (activeTab.value === "video") {
    startVideoGeneration();
  } else {
    startGeneration();
  }
};

/**
 * 下载生成的图片
 * @param {string} imageUrl - 图片URL
 * @param {string} imageName - 图片名称
 */
const downloadImage = (imageUrl, imageName) => {
  try {
    const link = document.createElement("a");
    link.href = imageUrl;
    const fileName = `${imageName || "数字人形象"}_${new Date().getTime()}.png`;
    link.download = fileName;

    document.body.appendChild(link);
    link.click();
    document.body.removeChild(link);

    ElMessage.success("图片下载成功");
  } catch (error) {
    console.error("下载图片失败:", error);
    ElMessage.error("图片下载失败，请重试");
  }
};

/**
 * 处理视频人物图片变更
 */
const handleVideoImageChange = file => {
  videoImageFile.value = file.raw;
  videoImageUrl.value = URL.createObjectURL(file.raw);
};

// 修改视频生成相关的方法
const startVideoGeneration = () => {
  if (isGenerating.value) return;

  if (!videoImageUrl.value) {
    ElMessage.warning("请先上传人物图片");
    return;
  }

  if (!videoDescription.value) {
    ElMessage.warning("请填写场景描述");
    return;
  }

  // 调用新的视频生成API
  generateVideo();
};

const generateVideo = async () => {
  isGenerating.value = true;
  generationProgress.value = 0;
  hasResults.value = false;
  showSuccessAnimation.value = false;

  // 更新进度步骤为视频生成的步骤
  progressSteps.splice(
    0,
    progressSteps.length,
    { progress: 10, text: "处理上传图片..." },
    { progress: 25, text: "提交生成任务..." },
    { progress: 40, text: "等待任务处理..." },
    { progress: 70, text: "获取视频结果..." },
    { progress: 100, text: "生成完成!" }
  );

  try {
    // 设置进度到10%
    generationProgress.value = 10;

    // 构建提示词
    const prompt = `${videoDescription.value}，风格：${
      videoStyle.value === "ancient"
        ? "古风"
        : videoStyle.value === "modern"
          ? "现代"
          : "武侠"
    }`;

    // 使用新的文件上传接口
    generationProgress.value = 25;

    const response = await uploadImageForVideo(
      videoImageFile.value,
      prompt,
      "9:16" // 默认使用9:16的宽高比
    );

    console.log("视频生成响应:", response);

    // 检查响应是否成功
    if (!response || response.data === undefined) {
      throw new Error("视频生成失败，返回数据无效");
    }

    // 如果返回的是视频任务ID
    if (response.data !== null && typeof response.data === "string" && !response.data.startsWith("http")) {
      // 保存任务ID到pinia
      const taskId = response.data;
      videoStore.setPendingTaskId(taskId);

      // 开始轮询任务状态
      generationProgress.value = 40;
      await pollTaskStatus(taskId);
    }
    // 如果直接返回视频URL
    else if (response.data !== null && typeof response.data === "string" && response.data.startsWith("http")) {
      generationProgress.value = 90;
      handleSuccessResult(response.data);
    }
    // 如果返回的是对象
    else if (response.data && response.data.video_url) {
      generationProgress.value = 90;
      handleSuccessResult(response.data.video_url);
    } else {
      throw new Error("视频生成失败，未返回有效数据");
    }
  } catch (error) {
    console.error("视频生成失败:", error);
    ElMessage.error("视频生成失败，请稍后重试");
    isGenerating.value = false;
  }
};

/**
 * 轮询查询任务状态
 */
const pollTaskStatus = async taskId => {
  let retryCount = 0;
  const maxRetries = 30; // 增加最大重试次数，视频生成可能需要较长时间
  const interval = 3000; // 轮询间隔(ms)

  const pollInterval = setInterval(async () => {
    try {
      if (retryCount >= maxRetries) {
        clearInterval(pollInterval);
        ElMessage.info("视频生成需要较长时间，您可以稍后回来查看结果");
        isGenerating.value = false;
        return;
      }

      retryCount++;

      // 计算动态进度，从40%到70%之间
      generationProgress.value = Math.min(70, 40 + retryCount);

      // 查询任务状态
      const result = await getVideoTaskResult(taskId);
      console.log("查询任务结果:", result);

      // 检查任务是否完成
      if (result && result.code === 200 && result.data) {
        // 如果返回的是URL，表示生成成功
        if (typeof result.data === "string" && result.data.startsWith("http")) {
          clearInterval(pollInterval);

          try {
            // 使用getVideo获取视频数据
            let video = await getVideo(result.data);
            
            // 检查video响应是否有效
            if (video && video.data) {
              videoStore.clearPendingTask(); // 清除存储的任务ID
              // 传递视频数据
              handleSuccessResult(video.data);
            } else {
              throw new Error("获取到的视频数据无效");
            }
          } catch (videoError) {
            console.error("获取视频数据失败:", videoError);
            ElMessage.error("获取视频数据失败，请重试");
            videoStore.clearPendingTask(); // 清除存储的任务ID
            isGenerating.value = false;
          }
        }
        // 如果是视频对象
        else if (result.data.video_url) {
          clearInterval(pollInterval);
          videoStore.clearPendingTask(); // 清除存储的任务ID
          handleSuccessResult(result.data.video_url);
        }
        // 如果返回失败状态
        else if (result.data.status === "failed") {
          clearInterval(pollInterval);
          videoStore.clearPendingTask(); // 清除存储的任务ID
          ElMessage.error(
            "视频生成失败: " + (result.data.message || "未知错误")
          );
          isGenerating.value = false;
        }
        // 否则继续轮询
      }
    } catch (error) {
      console.error("查询任务状态失败:", error);
      // 发生错误时不停止轮询，继续尝试
    }
  }, interval);
};

/**
 * 处理成功的结果
 * @param {string} videoUrl 视频URL
 */
const handleSuccessResult = async videoUrl => {
  try {
    // 确保videoUrl不为空
    if (!videoUrl) {
      throw new Error("视频URL为空");
    }

    console.log("处理视频结果:", videoUrl);
    
    // 视频生成完成，显示成功动画
    generationProgress.value = 100;

    setTimeout(() => {
      isGenerating.value = false;
      showSuccessAnimation.value = true;

      setTimeout(async () => {
        showSuccessAnimation.value = false;
        hasResults.value = true;

        // 添加生成结果，保存原始URL
        videoResults.value = [
          {
            video: videoUrl, // 原始URL
            poster: videoImageUrl.value,
            style: getVideoStyleName(videoStyle.value),
            duration: `${videoDuration.value}秒`
          }
        ];

        // 保存到历史记录
        saveVideoHistory(
          videoUrl,
          videoImageUrl.value,
          getVideoStyleName(videoStyle.value)
        );

        // 预先加载视频，确保能正确播放
        if (videoUrl) {
          try {
            const blobUrl = await createBlobUrlFromVideo(videoUrl);
            if (blobUrl && blobUrl !== videoUrl) {
              // 保存创建的blob URL以便后续清理
              videoBlobUrls.value.push(blobUrl);
              // 更新视频结果为blob URL
              videoResults.value[0].video = blobUrl;
            }
          } catch (error) {
            console.error("预加载视频失败:", error);
            // 即使预加载失败，也尝试使用原始URL
            ElMessage.warning("视频预加载失败，可能影响播放体验");
          }
        }
      }, 2000);
    }, CONSTANTS.ANIMATION_DELAY);
  } catch (error) {
    console.error("处理视频结果失败:", error);
    ElMessage.error("处理视频结果失败: " + error.message);
    isGenerating.value = false;
  }
};

// 获取视频风格名称
const getVideoStyleName = styleValue => {
  switch (styleValue) {
    case "ancient":
      return "古风汉服";
    case "modern":
      return "现代风格";
    case "martial":
      return "武侠风格";
    default:
      return "自定义风格";
  }
};

/**
 * 下载生成的视频
 * @param {string} videoUrl - 视频URL
 * @param {string} videoName - 视频名称
 */
const downloadVideo = (videoUrl, videoName) => {
  try {
    const link = document.createElement("a");
    link.href = videoUrl;
    const fileName = `${videoName || "汉服视频"}_${new Date().getTime()}.mp4`;
    link.download = fileName;

    document.body.appendChild(link);
    link.click();
    document.body.removeChild(link);

    ElMessage.success("视频下载成功");
  } catch (error) {
    console.error("下载视频失败:", error);
    ElMessage.error("视频下载失败，请重试");
  }
};

/**
 * 处理视频点击播放
 */
const handleVideoClick = event => {
  try {
    // 通过事件获取当前视频元素
    const videoElement = event.target.closest("video");
    if (!videoElement) {
      console.warn("未找到视频元素");
      return;
    }

    // 获取视频URL
    const videoUrl = videoResults.value[0]?.video;
    if (!videoUrl) {
      console.warn("视频URL不存在");
      return;
    }

    console.log("播放视频:", videoUrl);
    
    // 使用工具函数播放视频
    playVideo(videoElement, videoUrl).catch(error => {
      console.error("播放视频失败:", error);
      ElMessage.error("播放视频失败，请重试");
    });
  } catch (error) {
    console.error("处理视频点击事件失败:", error);
    ElMessage.error("播放视频失败，请重试");
  }
};

/**
 * 组件卸载前清理所有创建的blob URL
 */
onBeforeUnmount(() => {
  // 清理所有创建的blob URL
  videoBlobUrls.value.forEach(url => {
    revokeBlobUrl(url);
  });
  videoBlobUrls.value = [];
});

// 播放历史记录中的视频
const playRecentVideo = item => {
  try {
    console.log("播放历史视频:", item);
    
    if (!item || !item.video) {
      console.warn("无法播放该视频，视频数据无效");
      ElMessage.warning("无法播放该视频，视频数据无效");
      return;
    }

    // 将选中的历史视频添加到当前视频结果
    videoResults.value = [
      {
        video: item.video,
        poster: item.poster || defaultPoster.value,
        style: item.style || "历史视频",
        duration: item.duration || ""
      }
    ];

    // 显示结果区域
    hasResults.value = true;
    
    console.log("设置当前视频结果:", videoResults.value);

    // 滚动到视频播放区域
    nextTick(() => {
      const videoElement = document.querySelector(".video-result-grid");
      if (videoElement) {
        videoElement.scrollIntoView({ behavior: "smooth" });
        
        // 尝试自动播放视频
        setTimeout(() => {
          const videoPlayer = videoElement.querySelector("video");
          if (videoPlayer) {
            console.log("尝试自动播放视频");
            videoPlayer.play().catch(err => {
              console.warn("自动播放失败，可能需要用户交互:", err);
            });
          }
        }, 500);
      } else {
        console.warn("未找到视频元素，无法滚动");
      }
    });
  } catch (error) {
    console.error("播放历史视频失败:", error);
    ElMessage.error("播放历史视频失败，请重试");
  }
};

// 保存视频生成记录到本地存储
const saveVideoHistory = (videoUrl, posterUrl, style) => {
  try {
    console.log("保存视频历史记录:", { videoUrl, posterUrl, style });
    
    // 获取现有记录
    const historyJson = localStorage.getItem("video-history") || "[]";
    const history = JSON.parse(historyJson);
    console.log("现有历史记录:", history);

    // 添加新记录到开头
    const newRecord = {
      video: videoUrl,
      poster: posterUrl,
      style: style,
      duration: `${videoDuration.value}秒`,
      createdAt: new Date().toISOString()
    };
    history.unshift(newRecord);
    console.log("添加新记录:", newRecord);

    // 最多保留10条记录
    const limitedHistory = history.slice(0, 10);

    // 保存回本地存储
    localStorage.setItem("video-history", JSON.stringify(limitedHistory));
    console.log("保存到localStorage成功");

    // 更新显示
    recentVideoResults.value = limitedHistory;
    console.log("更新历史记录显示:", recentVideoResults.value);
    
    // 确保如果当前在视频标签页，历史记录会立即显示
    if (activeTab.value === "video") {
      nextTick(() => {
        console.log("视频标签页历史记录更新完成");
      });
    }
  } catch (error) {
    console.error("保存视频历史记录失败:", error);
    ElMessage.error("保存历史记录失败");
  }
};

// 加载视频历史记录
const loadVideoHistory = () => {
  try {
    console.log("开始加载视频历史记录");
    const historyJson = localStorage.getItem("video-history") || "[]";
    console.log("从localStorage获取的历史记录:", historyJson);
    
    const history = JSON.parse(historyJson);
    recentVideoResults.value = history;
    
    console.log("加载历史记录完成，数量:", recentVideoResults.value.length);
    console.log("历史记录内容:", recentVideoResults.value);
    
    return history; // 返回历史记录，方便调试
  } catch (error) {
    console.error("加载视频历史记录失败:", error);
    ElMessage.error("加载历史记录失败");
    recentVideoResults.value = [];
    return [];
  }
};
</script>

<style scoped>
.digital-figure-container {
  padding: 24px;
  max-width: 1280px;
  margin: 0 auto;
  min-height: 80vh;
  font-family: -apple-system, BlinkMacSystemFont, "SF Pro Text",
    "Helvetica Neue", Helvetica, Arial, sans-serif;
  padding-top: 0;
  max-width: unset;
}

.page-title {
  font-size: 28px;
  font-weight: 600;
  color: #1d1d1f;
  margin-bottom: 30px;
  text-align: center;
}

.content-wrapper {
  display: flex;
  gap: 30px;
  background-color: #f5f5f7;
  border-radius: 16px;
  padding: 30px;
  box-shadow: 0 4px 20px rgba(0, 0, 0, 0.05);
}

.upload-section,
.result-section {
  flex: 1;
  background-color: #ffffff;
  border-radius: 12px;
  padding: 24px;
  box-shadow: 0 2px 12px rgba(0, 0, 0, 0.04);
}

.section-title {
  margin-bottom: 24px;
  border-bottom: 1px solid #f0f0f0;
  padding-bottom: 16px;
}

.section-title h2 {
  font-size: 20px;
  font-weight: 600;
  color: #1d1d1f;
  margin-bottom: 8px;
}

.description {
  font-size: 14px;
  color: #86868b;
}

/* 人脸预览区域样式 */
.face-preview-area {
  margin-bottom: 20px;
}

.preview-title {
  font-size: 16px;
  font-weight: 500;
  margin-bottom: 10px;
  color: #333;
}

.face-preview {
  width: 100%;
  height: 200px;
  margin-bottom: 20px;
  border-radius: 8px;
  overflow: hidden;
  border: 1px solid #e6e6e6;
  background-color: #f5f5f7;
  display: flex;
  justify-content: center;
  align-items: center;
}

.face-preview-image {
  max-width: 100%;
  max-height: 100%;
  object-fit: contain;
}

.no-face-selected {
  text-align: center;
  padding: 20px;
  color: #909399;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 10px;
}

.no-face-selected .el-icon {
  font-size: 32px;
  color: #f56c6c;
  margin-bottom: 10px;
}

/* 描述区域样式 */
.description-area {
  margin-bottom: 20px;
  width: 100%;
}

.textarea-header {
  display: flex;
  align-items: center;
  margin-bottom: 8px;
}

.required-mark {
  color: #f56c6c;
  margin-right: 4px;
}

.description-area h3 {
  font-size: 16px;
  font-weight: 500;
  margin: 0;
}

.description-area :deep(.el-textarea__inner) {
  background-color: #f9f9f9;
  border-color: #e6e6e6;
  border-radius: 8px;
}

/* 风格选择区域 */
.style-selection {
  margin-bottom: 20px;
}

.style-selection :deep(.el-radio-button__inner) {
  padding: 8px 20px;
}

.progress-text {
  margin-top: 10px;
  text-align: center;
  color: #606266;
  font-size: 14px;
}

.generation-actions {
  text-align: center;
}

.generate-btn {
  width: 100%;
  height: 44px;
  font-weight: 500;
  font-size: 16px;
}

.result-grid {
  display: grid;
  grid-template-columns: repeat(2, 1fr);
  gap: 16px;
}

.result-item {
  border-radius: 8px;
  background-color: #f5f5f7;
  overflow: hidden;
  box-shadow: 0 2px 8px rgba(0, 0, 0, 0.05);
  transition:
    transform 0.3s ease,
    box-shadow 0.3s ease;
  display: flex;
  flex-direction: column;
}

.result-item:hover {
  transform: translateY(-4px);
  box-shadow: 0 4px 12px rgba(0, 0, 0, 0.1);
}

.result-image {
  width: 100%;
  height: 200px;
  object-fit: contain;
  border-radius: 8px 8px 0 0;
  background-color: #f5f5f7;
}

.result-item-footer {
  padding: 12px;
  background-color: white;
  display: flex;
  flex-direction: column;
  gap: 8px;
}

.result-style {
  font-size: 14px;
  color: #333;
  text-align: center;
  font-weight: 500;
}

.result-actions {
  text-align: center;
}

/* 媒体查询，确保在较小屏幕上也有良好的显示效果 */
@media (max-width: 1024px) {
  .content-wrapper {
    flex-direction: column;
  }

  .result-grid {
    grid-template-columns: repeat(2, 1fr);
  }
}

@media (max-width: 640px) {
  .result-grid {
    grid-template-columns: 1fr;
  }

  .face-preview {
    height: 180px;
  }
}

/* 空结果样式 */
.empty-result {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  min-height: 300px;
  background-color: #f9f9f9;
  border-radius: 8px;
  padding: 20px;
}

.empty-tip {
  margin-top: 12px;
  color: #909399;
  font-size: 14px;
}

/* 全局进度条样式 */
.global-progress-container {
  position: fixed;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
  background-color: rgba(0, 0, 0, 0.75);
  display: flex;
  justify-content: center;
  align-items: center;
  z-index: 9999;
  backdrop-filter: blur(8px);
  animation: fadeIn 0.3s ease;
}

@keyframes fadeIn {
  from {
    opacity: 0;
  }
  to {
    opacity: 1;
  }
}

.global-progress-card {
  background: linear-gradient(135deg, #e3f2fd, #bbdefb);
  border-radius: 12px;
  padding: 30px;
  width: 550px;
  max-width: 90%;
  box-shadow:
    0 10px 30px rgba(0, 0, 0, 0.2),
    0 0 20px rgba(33, 150, 243, 0.15);
  text-align: center;
  border: 1px solid rgba(255, 255, 255, 0.3);
  animation: slideUp 0.4s ease-out;
  overflow: hidden;
  position: relative;
}

@keyframes slideUp {
  from {
    transform: translateY(30px);
    opacity: 0;
  }
  to {
    transform: translateY(0);
    opacity: 1;
  }
}

.global-progress-card::before {
  content: "";
  position: absolute;
  top: -50%;
  left: -50%;
  width: 200%;
  height: 200%;
  background: radial-gradient(
    circle,
    rgba(255, 255, 255, 0.05) 0%,
    transparent 70%
  );
  z-index: 0;
}

.progress-header {
  display: flex;
  align-items: center;
  justify-content: center;
  margin-bottom: 25px;
  position: relative;
  z-index: 1;
}

.progress-icon {
  margin-right: 15px;
  color: #2196f3;
  animation: spin 2s linear infinite;
}

@keyframes spin {
  from {
    transform: rotate(0deg);
  }
  to {
    transform: rotate(360deg);
  }
}

.global-progress-card h3 {
  font-size: 22px;
  font-weight: 600;
  margin: 0;
  color: #0d47a1;
  text-shadow: 0 1px 2px rgba(255, 255, 255, 0.5);
  position: relative;
}

.global-progress-card .progress-text {
  margin-top: 20px;
  font-size: 16px;
  color: #1565c0;
  display: flex;
  flex-direction: column;
  align-items: center;
}

.progress-percentage {
  font-size: 24px;
  font-weight: 700;
  color: #1976d2;
  margin-bottom: 5px;
}

.global-progress-card :deep(.el-progress-bar__inner) {
  transition: all 0.5s ease-out;
}

.global-progress-card :deep(.el-progress-bar__outer) {
  background-color: rgba(33, 150, 243, 0.1);
  border-radius: 10px;
}

.progress-steps {
  display: flex;
  flex-direction: column;
  gap: 12px;
  margin-bottom: 25px;
  position: relative;
  z-index: 1;
}

.progress-step-item {
  display: flex;
  align-items: center;
  text-align: left;
  opacity: 0.5;
  transition: all 0.3s ease;
}

.progress-step-item.active {
  opacity: 1;
}

.step-dot {
  width: 10px;
  height: 10px;
  border-radius: 50%;
  background-color: #64b5f6;
  margin-right: 12px;
  position: relative;
}

.progress-step-item.active .step-dot {
  background-color: #2196f3;
  box-shadow: 0 0 10px rgba(33, 150, 243, 0.5);
}

.step-dot::before {
  content: "";
  position: absolute;
  width: 20px;
  height: 20px;
  border-radius: 50%;
  border: 2px solid #42a5f5;
  left: -7px;
  top: -7px;
  opacity: 0;
}

.progress-step-item.active .step-dot::before {
  animation: pulse 1.5s infinite;
}

@keyframes pulse {
  0% {
    transform: scale(0.8);
    opacity: 0.7;
  }
  70% {
    transform: scale(1.2);
    opacity: 0;
  }
  100% {
    transform: scale(0.8);
    opacity: 0;
  }
}

.step-text {
  font-size: 14px;
  color: #0d47a1;
}

.progress-step-item.active .step-text {
  color: #0d47a1;
  font-weight: 600;
}

/* 标题和操作按钮样式 */
.title-with-action {
  display: flex;
  justify-content: space-between;
  align-items: center;
  margin-bottom: 8px;
}

.regenerate-btn {
  font-size: 12px;
}

/* 成功动画样式 - 灵动岛风格 */
.success-animation-container {
  position: fixed;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
  background-color: rgba(255, 255, 255, 0.7);
  display: flex;
  justify-content: center;
  align-items: center;
  z-index: 9999;
  animation: backdropFadeIn 0.3s cubic-bezier(0.33, 1, 0.68, 1);
  backdrop-filter: blur(5px);
}

@keyframes backdropFadeIn {
  from {
    opacity: 0;
    backdrop-filter: blur(0);
  }
  to {
    opacity: 1;
    backdrop-filter: blur(5px);
  }
}

.success-animation {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
}

.dynamic-island {
  padding: 10px;
  perspective: 1000px;
}

.island-background {
  width: 250px;
  height: 250px;
  border-radius: 50px;
  background-color: #0a0a0a;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  position: relative;
  box-shadow: 0 12px 30px rgba(0, 0, 0, 0.3);
  animation: scaleIsland 0.5s cubic-bezier(0.34, 1.56, 0.64, 1);
  transform-origin: center center;
}

@keyframes scaleIsland {
  0% {
    transform: scale(0.3);
    opacity: 0;
  }
  40% {
    transform: scale(1.1);
  }
  60% {
    transform: scale(0.96);
  }
  80% {
    transform: scale(1.02);
  }
  100% {
    transform: scale(1);
    opacity: 1;
  }
}

.checkmark-wrapper {
  width: 80px;
  height: 80px;
  background-color: transparent;
  position: relative;
  margin-bottom: 16px;
  animation: fadeInWrapper 0.3s cubic-bezier(0.33, 1, 0.68, 1) forwards;
  opacity: 0;
  animation-delay: 0.2s;
}

@keyframes fadeInWrapper {
  from {
    opacity: 0;
    transform: translateY(10px);
  }
  to {
    opacity: 1;
    transform: translateY(0);
  }
}

/* SVG动画样式 */
.checkmark {
  width: 100%;
  height: 100%;
  border-radius: 50%;
  display: block;
  stroke-width: 3;
  stroke: #5ce679;
  stroke-miterlimit: 10;
  box-shadow: 0 0 15px #5ce679;
}

.checkmark-circle {
  stroke-dasharray: 166;
  stroke-dashoffset: 166;
  stroke-width: 2;
  stroke-miterlimit: 10;
  stroke: #5ce679;
  fill: none;
  animation: stroke 0.6s cubic-bezier(0.65, 0, 0.45, 1) forwards;
  animation-delay: 0.4s;
}

.checkmark-path {
  transform-origin: 50% 50%;
  stroke-dasharray: 48;
  stroke-dashoffset: 48;
  stroke-width: 3;
  stroke: #5ce679;
  animation: stroke 0.6s cubic-bezier(0.65, 0, 0.45, 1) forwards;
  animation-delay: 0.8s;
}

@keyframes stroke {
  100% {
    stroke-dashoffset: 0;
  }
}

.success-message {
  color: white;
  font-size: 18px;
  font-weight: 500;
  margin: 0;
  opacity: 0;
  animation: fadeInMessage 0.4s cubic-bezier(0.33, 1, 0.68, 1) forwards;
  animation-delay: 1.2s;
}

@keyframes fadeInMessage {
  from {
    opacity: 0;
    transform: translateY(10px);
  }
  to {
    opacity: 1;
    transform: translateY(0);
  }
}

/* 人脸模型库样式 */
.face-gallery-section {
  margin-bottom: 20px;
}

.section-header {
  display: flex;
  justify-content: space-between;
  align-items: center;
  margin-bottom: 15px;
}

.section-header h3 {
  font-size: 16px;
  font-weight: 500;
  margin: 0;
  color: #333;
}

.face-gallery {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  gap: 10px;
  margin-bottom: 15px;
}

.face-card {
  border-radius: 8px;
  overflow: hidden;
  background-color: #f9f9f9;
  border: 1px solid #eee;
  transition: all 0.2s;
  cursor: pointer;
  height: 130px;
  display: flex;
  flex-direction: column;
}

.face-card:hover {
  box-shadow: 0 2px 12px rgba(0, 0, 0, 0.1);
  transform: translateY(-2px);
}

.face-card.active {
  border: 2px solid #409eff;
  box-shadow: 0 0 8px rgba(64, 158, 255, 0.3);
}

.gallery-face-image {
  width: 100%;
  height: 90px;
  object-fit: contain;
  background-color: #f5f5f7;
}

.face-card-footer {
  padding: 5px 8px;
  font-size: 12px;
  display: flex;
  flex-direction: column;
  background-color: white;
  flex: 1;
}

.face-name {
  font-weight: 500;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.face-time {
  color: #999;
  font-size: 11px;
  margin-top: 2px;
}

.empty-gallery {
  background-color: #f9f9f9;
  border-radius: 8px;
  padding: 20px;
  text-align: center;
  color: #909399;
}

/* 对话框中的模型库样式 */
.faces-library {
  min-height: 200px;
}

.gallery-grid {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  gap: 15px;
}

.face-card-large {
  border-radius: 8px;
  overflow: hidden;
  background-color: #f9f9f9;
  border: 1px solid #eee;
  transition: all 0.2s;
  cursor: pointer;
  height: 180px;
  display: flex;
  flex-direction: column;
}

.face-card-large:hover {
  box-shadow: 0 3px 15px rgba(0, 0, 0, 0.1);
  transform: translateY(-3px);
}

.face-card-large.active {
  border: 2px solid #409eff;
  box-shadow: 0 0 12px rgba(64, 158, 255, 0.3);
}

.face-card-large .gallery-face-image {
  height: 140px;
}

@media (max-width: 768px) {
  .face-gallery {
    grid-template-columns: repeat(2, 1fr);
  }

  .gallery-grid {
    grid-template-columns: repeat(2, 1fr);
  }
}

@media (max-width: 480px) {
  .gallery-grid {
    grid-template-columns: 1fr;
  }
}

/* 添加新的样式 */
.tab-header {
  margin-bottom: 24px;
}

.feature-tabs {
  box-shadow: 0 4px 12px rgba(0, 0, 0, 0.05);
  border-radius: 8px;
  overflow: hidden;
}

.feature-tabs :deep(.el-tabs__header) {
  margin-bottom: 0;
  background: linear-gradient(to right, #f5f7fa, #e9f0f6);
}

.feature-tabs :deep(.el-tabs__item) {
  height: 50px;
  line-height: 50px;
  font-size: 16px;
  font-weight: 500;
  transition: all 0.3s;
}

.feature-tabs :deep(.el-tabs__item.is-active) {
  color: #1976d2;
  font-weight: 600;
}

.feature-tabs :deep(.el-tabs__active-bar) {
  background-color: #1976d2;
  height: 3px;
}

/* 修改视频参数布局 */
.video-params {
  margin-bottom: 20px;
}

.video-param-row {
  display: flex;
  gap: 16px;
  margin-bottom: 16px;
}

.param-group {
  margin-bottom: 20px;
  flex: 1;
}

.param-label {
  display: flex;
  align-items: center;
  margin-bottom: 8px;
  font-size: 14px;
  color: #606266;
}

.param-label .required-mark {
  color: #f56c6c;
  margin-right: 4px;
}

.param-select {
  width: 100%;
}

.param-select :deep(.el-input__wrapper) {
  background-color: #fff;
  border: 1px solid #dcdfe6;
  border-radius: 4px;
  box-shadow: none;
}

.video-style-container {
  width: 100%;
}

.button-group-container {
  width: 100%;
}

.video-style-group {
  width: 100%;
  display: flex;
}

.video-style-group :deep(.el-radio-button) {
  flex: 1;
}

.video-style-group :deep(.el-radio-button__inner) {
  width: 100%;
  display: block;
  text-align: center;
  font-size: 14px;
  padding: 10px 20px;
}

.scene-textarea {
  width: 100%;
}

.scene-textarea :deep(.el-textarea__inner) {
  background-color: #fff;
  border: 1px solid #dcdfe6;
  border-radius: 4px;
  font-size: 14px;
  padding: 8px 12px;
}

/* 改进响应式布局 */
@media (max-width: 768px) {
  .video-param-row {
    flex-direction: column;
    gap: 12px;
  }

  .video-style-group {
    flex-direction: column;
  }

  .video-style-group
    :deep(.el-radio-button:first-child .el-radio-button__inner) {
    border-radius: 4px 4px 0 0;
  }

  .video-style-group
    :deep(.el-radio-button:last-child .el-radio-button__inner) {
    border-radius: 0 0 4px 4px;
  }
}

/* 视频结果展示样式 */
.video-result-grid {
  display: grid;
  grid-template-columns: 1fr;
  gap: 20px;
}

.video-result-item {
  border-radius: 8px;
  background-color: #f5f5f7;
  overflow: hidden;
  box-shadow: 0 2px 8px rgba(0, 0, 0, 0.08);
  transition: all 0.3s ease;
}

.video-result-item:hover {
  transform: translateY(-4px);
  box-shadow: 0 8px 16px rgba(0, 0, 0, 0.1);
}

.result-video {
  width: 100%;
  height: auto;
  max-height: 400px;
  background-color: #000;
  display: block;
}

/* 修改结果展示区域样式以支持视频 */
.result-item {
  position: relative;
}

.result-item video {
  width: 100%;
  height: 200px;
  object-fit: contain;
  border-radius: 8px 8px 0 0;
  background-color: #f5f5f7;
}

/* 添加生成视频按钮的样式 */
.generate-video-btn {
  width: 100%;
  height: 44px;
  background-color: #409eff;
  border-color: #409eff;
  font-weight: 500;
  font-size: 16px;
  border-radius: 4px;
}

.generate-video-btn:hover {
  background-color: #66b1ff;
  border-color: #66b1ff;
}

.generate-video-btn:active {
  background-color: #3a8ee6;
  border-color: #3a8ee6;
}

/* 图片上传区域样式 */
.upload-image-area {
  margin-bottom: 20px;
}

.upload-container {
  border: 1px dashed #d9d9d9;
  border-radius: 6px;
  cursor: pointer;
  position: relative;
  overflow: hidden;
  background-color: #fafafa;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  margin-top: 8px;
}

.avatar-uploader {
  width: 100%;
  display: flex;
  justify-content: center;
}

.avatar-uploader-icon {
  font-size: 28px;
  color: #8c939d;
  width: 100%;
  height: 178px;
  text-align: center;
  display: flex;
  justify-content: center;
  align-items: center;
}

.upload-text {
  margin-top: 10px;
  font-size: 14px;
  color: #606266;
  position: absolute;
  bottom: 40px;
}

.uploaded-image {
  position: relative;
  width: 100%;
  height: 178px;
  display: flex;
  justify-content: center;
  align-items: center;
  overflow: hidden;
}

.uploaded-image:hover .image-hover-mask {
  opacity: 1;
}

.image-hover-mask {
  position: absolute;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
  background-color: rgba(0, 0, 0, 0.5);
  display: flex;
  flex-direction: column;
  justify-content: center;
  align-items: center;
  opacity: 0;
  transition: opacity 0.3s;
  color: white;
}

.upload-icon {
  font-size: 24px;
  margin-bottom: 8px;
}

.avatar {
  height: 100%;
  display: block;
  object-fit: contain;
}

.upload-tip {
  width: 100%;
  text-align: center;
  font-size: 12px;
  color: #909399;
  line-height: 30px;
  padding: 0 20px;
}

/* 添加最近生成历史记录样式 */
.recent-history-section {
  margin-top: 30px;
  background-color: #f9f9f9;
  border-radius: 10px;
  padding: 20px;
  box-shadow: 0 2px 10px rgba(0, 0, 0, 0.03);
}

.recent-videos-grid {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  gap: 15px;
  margin-top: 15px;
}

.recent-video-item {
  background-color: white;
  border-radius: 8px;
  overflow: hidden;
  box-shadow: 0 2px 8px rgba(0, 0, 0, 0.05);
  cursor: pointer;
  transition:
    transform 0.3s ease,
    box-shadow 0.3s ease;
}

.recent-video-item:hover {
  transform: translateY(-4px);
  box-shadow: 0 6px 12px rgba(0, 0, 0, 0.1);
}

.recent-thumbnail {
  position: relative;
  height: 120px;
  overflow: hidden;
  background-color: #eee;
}

.thumbnail-image {
  width: 100%;
  height: 100%;
  object-fit: cover;
}

.play-overlay {
  position: absolute;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
  background-color: rgba(0, 0, 0, 0.2);
  display: flex;
  justify-content: center;
  align-items: center;
  opacity: 0;
  transition: opacity 0.3s ease;
}

.recent-video-item:hover .play-overlay {
  opacity: 1;
}

.play-icon {
  font-size: 32px;
  color: white;
  filter: drop-shadow(0 2px 4px rgba(0, 0, 0, 0.5));
}

.recent-item-info {
  padding: 10px;
}

.recent-style {
  font-weight: 500;
  font-size: 14px;
  color: #333;
  margin-bottom: 5px;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.recent-time {
  font-size: 12px;
  color: #999;
}

@media (max-width: 1200px) {
  .recent-videos-grid {
    grid-template-columns: repeat(3, 1fr);
  }
}

@media (max-width: 768px) {
  .recent-videos-grid {
    grid-template-columns: repeat(2, 1fr);
  }
}

@media (max-width: 480px) {
  .recent-videos-grid {
    grid-template-columns: 1fr;
  }
}
</style>
};
